package com.ve.s2g.chain

import com.ve.s2g.getLogger
import com.ve.s2g.pojo.GitlabProject
import com.ve.s2g.pojo.Project
import com.ve.s2g.service.GitlabService
import com.ve.s2g.util.Constants
import com.ve.s2g.util.HttpClientManager
import org.dom4j.Attribute
import org.dom4j.io.SAXReader
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.context.ApplicationContext

/**
 *  项目初始化
 */
class ProjectInitializeHandle : AbstractHandler() {
    private val namespaceMap by lazy { Constants.GITLAB_NAMESPACE_CONFIG.split("\\s*-\\s+".toRegex()).associate {
        val (k, v) = it.split(":"); k to v
    }}

    override fun deal(dealObject: Any?) {
        val writelist = Constants.SVN_WRITE_LIST.split("\\s*-\\s*".toRegex()).toList()
        val result = mutableListOf<Project>()
        Constants.SVN_URL.split("\\s*-\\s*".toRegex()).forEach { svnroot: String ->
            val body = HttpClientManager.getSync(svnroot, Constants.SVN_USERNAME, Constants.SVN_PASSWORD)
            body.body()!!.byteStream().use {
                val doc = SAXReader().read(it)
                val atts = doc.selectNodes("//dir/@name")
                atts.map { attr: Any? ->
                    attr as Attribute
//                    println("$svnroot${attr.value}")
                    attr.value
                }.filter {
                    it in writelist
                }.forEach {
                    result.add(Project(it))
                }
            }
        }

        result.forEach { project: Project ->
            try {
                val url = "${Constants.GITLAB_URL}/api/v4/projects?private_token=${Constants.GITLAB_PRIVATE_TOKEN}&search=${project.name}&simple=true"
                val gitlabProjects = gitlabService!!.searchProject(url)
                //getLogger<ProjectInitializeHandle>().error(JSONArray.toJSONString(gitlabProjects))
                var needmove = true;
                if (gitlabProjects!!.size <= 0) {
                    val createProjectUrl = "${Constants.GITLAB_URL}/api/v4/projects?private_token=${Constants.GITLAB_PRIVATE_TOKEN}"
                    var newGitlabProject = GitlabProject(name = project.name)
                    newGitlabProject = gitlabService!!.createProject(newGitlabProject, createProjectUrl)
                    project.id = newGitlabProject.id
                } else {
                    project.id = gitlabProjects[0].id
                    getLogger<ProjectInitializeHandle>().info("${project.name} in gitlab exsit. ")
                    needmove = gitlabProjects.map{ it.path_with_namespace==namespaceMap[project.name]}.reduce { acc, b -> acc||b}
                }
                if(needmove){
                    val mvUrl =
                        "${Constants.GITLAB_URL}/api/v4/projects/${project.id}/transfer?private_token=${Constants.GITLAB_PRIVATE_TOKEN}"
                    gitlabService!!.moveProject(project, namespaceMap[project.name] as String, mvUrl)
                }
            } catch (e: Exception) {
                getLogger<ProjectInitializeHandle>().error("create ${project.name} fail. ", e)
            }
            project.gitUrl = Constants.GITLAB_URL
            project.gitNameSpace= namespaceMap[project.name] as String
        }
        nextHandler!!.deal(result)
    }

}

